Skip to content

Challenge 23: Verify safety of Vec functions part 1#569

Open
Samuelsills wants to merge 3 commits intomodel-checking:mainfrom
Samuelsills:challenge-23-vec-pt1-pr
Open

Challenge 23: Verify safety of Vec functions part 1#569
Samuelsills wants to merge 3 commits intomodel-checking:mainfrom
Samuelsills:challenge-23-vec-pt1-pr

Conversation

@Samuelsills
Copy link
Copy Markdown

Summary

Add Kani proof harnesses for all 36 Vec functions specified in Challenge #23:

from_raw_parts, from_nonnull, from_nonnull_in, into_raw_parts_with_alloc, into_boxed_slice, truncate, set_len, swap_remove, insert, remove, retain_mut, dedup_by, push, push_within_capacity, pop, append, append_elements, drain, clear, split_off, leak, spare_capacity_mut, split_at_spare_mut, split_at_spare_mut_with_len, extend_from_within, into_flattened, extend_with, spec_extend_from_within, deref, deref_mut, into_iter, extend_desugared, extend_trusted, extract_if, drop, try_from

All harnesses verified locally with Kani.

Resolves #284

Samuelsills and others added 3 commits March 26, 2026 15:39
Add Kani proof harnesses for all 36 Vec functions specified in
Challenge model-checking#23, including from_raw_parts, set_len, push, pop, insert,
remove, swap_remove, truncate, drain, split_off, append, retain_mut,
dedup_by, extend_from_within, extract_if, and other core Vec
operations. Resolves model-checking#284

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@Samuelsills Samuelsills marked this pull request as ready for review March 26, 2026 22:29
@Samuelsills Samuelsills requested a review from a team as a code owner March 26, 2026 22:29
@Samuelsills
Copy link
Copy Markdown
Author

Verification Coverage Report

Functions Verified (36/36 ✅)

from_raw_parts, from_nonnull (→from_parts), from_nonnull_in (→from_parts_in), into_raw_parts_with_alloc, into_boxed_slice, truncate, set_len, swap_remove, insert, remove, retain_mut, dedup_by, push, push_within_capacity, pop, append, append_elements, drain, clear, split_off, leak, spare_capacity_mut, split_at_spare_mut, split_at_spare_mut_with_len, extend_from_within, into_flattened, extend_with, spec_extend_from_within, deref, deref_mut, into_iter, extend_desugared, extend_trusted, extract_if, drop, try_from

UBs Checked (automatic via Kani/CBMC)

  • ✅ Accessing dangling or misaligned pointers
  • ✅ Reading from uninitialized memory
  • ✅ Mutating immutable bytes
  • ✅ Producing an invalid value

Verification Approach

  • Tool: Kani Rust Verifier
  • 36 proof harnesses, one per spec function
  • Note: spec names from_nonnull/from_nonnull_in map to source names from_parts/from_parts_in

@feliperodri feliperodri added the Challenge Used to tag a challenge label Mar 29, 2026
@feliperodri feliperodri requested a review from Copilot March 31, 2026 22:18
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a Kani verification module (#[cfg(kani)] mod verify) in alloc::vec with proof harnesses covering a large set of Vec APIs as part of Challenge #23 (pointer arithmetic / safety validation).

Changes:

  • Reworked the existing verify_swap_remove harness to a simpler bounds-checked index + postcondition.
  • Added many new Kani proof harnesses for additional Vec methods (mutation, raw parts conversions, iteration, spare capacity APIs, etc.).
  • Introduced a Vec::leak harness that attempts to reclaim leaked memory for verification runs.

Comment on lines +4409 to 4411
unsafe {
drop(crate::boxed::Box::from_raw(leaked as *mut [i32]));
}
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

verify_leak attempts to “unleak” the returned slice by converting &mut [i32] into Box<[i32]> via Box::from_raw. This deallocation is only sound if the Vec’s allocation has no excess capacity (i.e., capacity == len) and uses the global allocator; otherwise the dealloc layout can mismatch the original allocation, which is UB. Prefer not deallocating here (accept the leak in the harness), or restructure the harness to avoid Vec::leak cleanup via Box::from_raw (e.g., only perform such cleanup when you can guarantee capacity == len).

Suggested change
unsafe {
drop(crate::boxed::Box::from_raw(leaked as *mut [i32]));
}

Copilot uses AI. Check for mistakes.
Comment on lines +4327 to +4333
#[kani::proof]
pub fn verify_push() {
let arr: [i32; ARRAY_LEN] = kani::Arbitrary::any_array();
let mut v = Vec::from(&arr);
v.push(kani::any());
assert!(v.len() == ARRAY_LEN + 1);
}
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Several harnesses in this #[cfg(kani)] module call Vec APIs that are themselves #[cfg(not(no_global_oom_handling))] (e.g., push, reserve, insert, into_boxed_slice, extend_from_within, append). Under a build that enables no_global_oom_handling together with kani, these harnesses won’t compile because those methods are not available. Consider adding matching #[cfg(not(no_global_oom_handling))] gates to the affected proof functions (or otherwise gating the whole verify module) so cfg combinations remain buildable.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Challenge Used to tag a challenge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Challenge 23: Verify the safety of Vec functions part 1

3 participants